/*
 * File:   Creature.cpp
 * Author: Elevator
 *
 * Created on 12 Май 2013 г., 23:42
 */

#include "Creature.h"
#include <set>
#include <queue>

Creature::Creature( std::string id ) :
	_id( id ),
	_head( 0 ),
	_partsCount( 0 )
{
}

Creature::~Creature( )
{
}

std::string Creature::GetId( ) const
{
	return _id;
}

void Creature::AddPart( IPart* part )
{
	if( _partsCount == 0 )
		_head = part;
	_parts.AddNode( part );
	_partsCount++;
}

void Creature::RemovePart( IPart* part )
{
	if( *part == *_head )
		_head = 0;
	_parts.RemoveNode( part );
	_partsCount--;
}

void Creature::ProcessCommand( const Command& command )
{
	std::set<IPart*> set;

	std::queue<IPart*> queue;
	queue.push( _head );
	while( !queue.empty( ) )
	{
		IPart* part = queue.front( );
		queue.pop( );
		part->ProcessCommand( command );

		for( IteratorPtr<IPart*> neighbors( _parts.GetNeihgbors( part )->GetIterator( ) );
				!neighbors->IsEnd( );
				neighbors->Next( ) )
		{
			IPart* nextPart = neighbors->Current( );
			if( set.find( nextPart ) == set.end( ) )
			{
				set.insert( nextPart );
				queue.push( nextPart );
			}
		}
	}
	set.clear( );
}

void Creature::Update( float dt )
{
	for( IteratorPtr<IPart*> parts( _parts.GetNodes( )->GetIterator( ) );
			!parts->IsEnd( );
			parts->Next( ) )
	{
		parts->Current( )->Update( dt );
	}
}

void Creature::Draw( ) const
{
	for( IteratorPtr<IPart*> parts( _parts.GetNodes( )->GetIterator( ) );
			!parts->IsEnd( );
			parts->Next( ) )
	{
		parts->Current( )->Draw( );
	}
}

void Creature::LinkParts( IPart* partA, IPart* partB )
{
	_parts.SetLinked( partA, partB, true );
}

const IIterable<IPart*>* Creature::GetParts( )
{
	return _parts.GetNodes( );
}

